package cn.ilovese.collect.serviceimpl.coordination;

import cn.ilovese.collect.datamapper.coordination.CoordinationAbilityMapper;
import cn.ilovese.collect.datamapper.coordination.CoordinationRankingMapper;
import cn.ilovese.collect.datamapper.report.ReportMapper;
import cn.ilovese.collect.datamapper.user.UserMapper;
import cn.ilovese.collect.po.coordination.CoordinationAbility;
import cn.ilovese.collect.po.coordination.CoordinationRanking;
import cn.ilovese.collect.po.coordination.ReportTask;
import cn.ilovese.collect.po.user.User;
import cn.ilovese.collect.service.coordination.CoordinationService;
import cn.ilovese.collect.util.Constant;
import cn.ilovese.collect.vo.Coordination.CoordinationAbilityVO;
import cn.ilovese.collect.vo.Coordination.WorkerSimilarityVO;
import cn.ilovese.collect.vo.ResultVO;
import cn.ilovese.collect.vo.similarity.ReportSimilarityVO;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

@Service
@CacheConfig(cacheNames = "coordination",cacheManager = "cacheManager")
public class CoordinationServiceImpl implements CoordinationService {

    @Resource
    CoordinationAbilityMapper coordinationAbilityMapper;
    @Resource
    CoordinationRankingMapper coordinationRankingMapper;
    @Resource
    ReportMapper reportMapper;
    @Resource
    UserMapper userMapper;

//    private final HashMap<String, Integer> field = new HashMap<String, Integer>(){
//        {
//            field.put("function_test",1);
//            field.put("performance_test",2);
//            field.put("bug_explore",3);
//        }
//    };

    @Override
    public ResultVO<CoordinationAbilityVO> getCoordinationAbility(Integer userId) {
        //排除是非worker的情况
        User user = userMapper.selectByPrimaryKey(userId);
        if(!user.getRole().equals("worker"))
            return new ResultVO<>(Constant.REQUEST_FAIL, "该用户不是工人", new CoordinationAbilityVO());
        CoordinationAbility coordinationAbility = coordinationAbilityMapper.selectByUserId(userId);
        if(coordinationAbility == null)
            return new ResultVO<>(Constant.REQUEST_SUCCESS, "报告协作数目少于1篇", new CoordinationAbilityVO());
        Integer reportNum = coordinationAbility.getReportNum();
        //报告数目不足3个，这个时候应该不显示相似度信息
        if(reportNum < 1)
            return new ResultVO<>(Constant.REQUEST_SUCCESS, "报告协作数目少于1篇", new CoordinationAbilityVO());
        CoordinationAbilityVO coordinationAbilityVO = new CoordinationAbilityVO();
        Double badRate = 0.0;
        Integer badNum = coordinationAbility.getBadReportNum();
        if(badNum == 0)   //没有错误报告，肯定该认为是1
            badRate = 1.0;
        if(badNum != 0)
            badRate = coordinationAbility.getModifiedReportNum().doubleValue() / coordinationAbility.getBadReportNum().doubleValue();
        //六四开计算，num占到五分里面的三分，badRate占到五分里面的两分
        //number>=1, badRate在0-1之间，要差不多统一到5
        Integer tempNum = reportNum;
        if(tempNum > 10)
            tempNum = 10;
        Double enthusiasm = tempNum.doubleValue() * 0.3 + badRate * 2;
        Double goodRate = (reportNum.doubleValue() - badNum.doubleValue()) / reportNum.doubleValue();
        coordinationAbilityVO.setUserId(userId);
        coordinationAbilityVO.setCoordinateNum(reportNum);
        coordinationAbilityVO.setBadReportModifyRate(badRate);
        coordinationAbilityVO.setEnthusiasm(enthusiasm);
        coordinationAbilityVO.setGoodReportRate(goodRate);
        //获取一个用户对应的所有领域的报告情况,可以考虑连接查询，把所有连接后的对象返回回来
        //这样既可以计算每一个领域的得分，也可以计算平均文本相似度和图片相似度
        List<ReportTask> reportTasks = reportMapper.selectReportTaskByUserid(userId); //拿到了带有报告和task信息的po
        Integer totalNum = 0;   //总报告数目木
        List<ReportSimilarityVO> reportSimilarities = new ArrayList<>();
        //下标1，2，3分别对应功能测试，性能测试，bug探索
        Double[] fieldSims = new Double[]{0.0,0.0,0.0,0.0};
        Integer[] fieldNums = new Integer[]{0,0,0,0};
        Double avgTextSim = 0.0;
        Double avgPicSim = 0.0;
        HashMap<String, Integer> field = new HashMap<String, Integer>();
        field.put("function_test",1);
        field.put("performance_test",2);
        field.put("bug_explore",3);
        for(ReportTask reportTask: reportTasks){
            //说明这个报告的相似度还没算完
            if(reportTask.getTextSimilarity() == null || reportTask.getPicSimilarity() == null)
                continue;
            totalNum++;
            avgTextSim += reportTask.getTextSimilarity();
            avgPicSim += reportTask.getPicSimilarity();
            //判断属于哪一个领域，并对对应领域赋值
            Integer type = field.get(reportTask.getTaskType());
            fieldNums[type] ++;
            fieldSims[type] += (reportTask.getTextSimilarity() + reportTask.getPicSimilarity()) / 2;
            //加入reportSimilarities中
            reportSimilarities.add(new ReportSimilarityVO(reportTask.getId(),reportTask.getTextSimilarity(),reportTask.getPicSimilarity()));
        }
        //计算总报告相似度
        avgTextSim /= totalNum;
        avgPicSim /= totalNum;
        coordinationAbilityVO.setAvgTextSim(avgTextSim);
        coordinationAbilityVO.setAvgPicSim(avgPicSim);
        coordinationAbilityVO.setSimList(reportSimilarities);
        //按照相似度6，报告数量4计算擅长的领域，使用fieldSims来保存。注意报告数量要现*0.1保证在同一个量级上
        //fieldNums相似度越高说明越不好，因此要考虑用1减去
        for(int i = 1; i <= 3; i ++){
            //首先计算平均相似度
            if(fieldNums[i] == 0)
                //说明这个field是0，跳过就行了
                continue;
            fieldSims[i] = fieldSims[i] / fieldNums[i];
            System.out.println(fieldSims[i]);
            fieldSims[i] = (1-fieldSims[i]) * 6 + fieldNums[i] * 0.4;
        }
        //判断哪个领域数值最大
        int type = -1;
        double max = -1.0;
        for(int i = 1; i <= 3; i ++){
            if(fieldSims[i] > max){
                max = fieldSims[i];
                type = i;
            }
        }
        String key = "";
        //获取对应的领域string
        for(String getkey: field.keySet()){
            if(field.get(getkey).equals(type)){
                key = getkey;
                break;
            }
        }
        coordinationAbilityVO.setSkill(key);
        //查找用户的ranking
        List<CoordinationRanking> rankings = coordinationRankingMapper.selectAll();
        Integer userRank = 0;
        int idx = 0;
        List<WorkerSimilarityVO> workerSimilarities = new ArrayList<>();
        for (CoordinationRanking coordinationRanking : rankings) {
            idx++;
            if (coordinationRanking.getUserId().equals(userId))
                userRank = idx;
            workerSimilarities.add(new WorkerSimilarityVO(coordinationRanking.getUserId(), coordinationRanking.getTotalSimilarity()));
        }
        System.out.println("userRank:" + userRank);
        Double rank = userRank.doubleValue() / rankings.size();
        coordinationAbilityVO.setRank(rank);
        coordinationAbilityVO.setWorkerSimilarities(workerSimilarities);
        Double generalScore = 0.0;
        //根据积极性（0-5），优质报告率，独特性排名算分数，总分0-1
        //比例是3，4，3
        generalScore = enthusiasm / 5 * 0.3 + goodRate * 0.4 + (1 - rank) * 0.5;
        coordinationAbilityVO.setScore(generalScore);
        return new ResultVO<>(Constant.REQUEST_SUCCESS, "返回成功",coordinationAbilityVO);
    }
}
